/**  
* Copyright (c) 2009, Noel Lynch All rights reserved. Redistribution and use  
* in source and binary forms, with or without modification, are permitted  
* provided that the following conditions are met: Redistributions of source  
* code must retain the above copyright notice, this list of conditions and the  
* following disclaimer. Redistributions in binary form must reproduce the above  
* copyright notice, this list of conditions and the following disclaimer in the  
* documentation and/or other materials provided with the distribution. Neither  
* the name of Noel Lynch nor the names of contributors may be used to  
* endorse or promote products derived from this software without specific prior  
* written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR  
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
*/
// created by noellynch
// Oct 16, 2009

package com.sceneworker.editors.texturepainter;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import net.miginfocom.swing.MigLayout;

import com.jme.image.Image;
import com.jme.image.Texture;
import com.jme.math.Vector2f;
import com.myjavautils.swing.MigLayoutUtils;
import com.myjavautils.swing.SimpleAlert;
import com.myjavautils.swing.SwingComponentFactory;
import com.sceneworker.editors.texturepainter.TextureBufferedImageRep.MixType;
import com.sceneworker.editors.texturepainter.brushgenerator.BrushImage;
import com.sceneworker.editors.texturepainter.brushgenerator.BrushSpectrumCalculator;
import com.sceneworker.util.swing.RGBEditorPanel;

public class TexturePainterPanel extends JPanel {

	private		TextureImagePaintableComponent		mcl_textureImgComp;
	private		BrushImage							mcl_brushImage;
	private		JLabel								mcl_textureName;
	
	public	TexturePainterPanel(Texture cl_texture) {
		Image	lcl_textureImage = null;
		if(cl_texture != null) {
			lcl_textureImage = cl_texture.getImage();
			
			if(lcl_textureImage == null) {
				SimpleAlert.doAlert("This texture does not have an image associated with it. Painting cannot be carried out.", this);
				return;
			}
		}
		
		setLayout(new MigLayout("inset 5"));
		
		initialiseBrushImage();
		initialiseTexturePaintParams();
		
		if(cl_texture != null) {
			mcl_textureImgComp = new TextureImagePaintableComponent(lcl_textureImage, cl_texture, mcl_brushImage);
		} else {
			mcl_textureImgComp = new TextureImagePaintableComponent(mcl_brushImage);
		}
		
		updateName();
		
		add(mcl_textureImgComp, "wrap, width 100%, height 100%");
	}
	
	public	void	updateWithNewTexture(Texture cl_texture) {
		mcl_textureImgComp.updateData(cl_texture);
		updateName();
	}
	
	public	void	updateName() {
		if(mcl_textureImgComp.getTextureRep() != null) {
			if(mcl_textureImgComp.getTextureRep().getTexture() != null) {
				if(mcl_textureImgComp.getTextureRep().getTexture().getImageLocation() != null) {
					mcl_textureName.setText("Texture : " + mcl_textureImgComp.getTextureRep().getTexture().getImageLocation());
				}
			}
		} else {
			mcl_textureName.setText("Texture : Unknown");
		}
	}
	
	public	BrushImage	getBrush() {
		return mcl_brushImage;
	}
	
	public	void	paintFromUV(Vector2f cl_uv) {
		mcl_textureImgComp.paintMouse(cl_uv);
	}
	
	private	void	initialiseTexturePaintParams() {
		MigLayoutUtils.makeLabelAndSeperator(this, "Texture Channel");
		mcl_textureName = SwingComponentFactory.makeALabel("");
		add(mcl_textureName, "wrap");
		
		add(SwingComponentFactory.makeALabel("Channel"), "split");
		JComboBox		lcl_comboChannel = SwingComponentFactory.makeAComboBox();
		lcl_comboChannel.addItem(TextureBufferedImageRep.ImageMode.rgba);
		lcl_comboChannel.addItem(TextureBufferedImageRep.ImageMode.alpha);
		
		lcl_comboChannel.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				mcl_textureImgComp.setImageDisplayMode((TextureBufferedImageRep.ImageMode)e.getItem());
			}
			
		});
		add(lcl_comboChannel);
		
		add(SwingComponentFactory.makeALabel("Zoom"));
		JComboBox		lcl_comboZoom = SwingComponentFactory.makeAComboBox();
		lcl_comboZoom.addItem("100");
		lcl_comboZoom.addItem("200");
		lcl_comboZoom.addItem("300");
		
		lcl_comboZoom.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				String		lstr_temp = (String)e.getItem();
				mcl_textureImgComp.setZoom(Integer.parseInt(lstr_temp) / 100);
			}
		});
		add(lcl_comboZoom, "wrap");
	}
	
	private	void	initialiseBrushImage() {
		MigLayoutUtils.makeLabelAndSeperator(this, "Brush");
		final	BrushSpectrumCalculator		lcl_calculator = new BrushSpectrumCalculator();
		mcl_brushImage = new BrushImage(lcl_calculator);
		add(mcl_brushImage, "split");
		
		JPanel		lcl_p = MigLayoutUtils.makeStandardPanel();
		final		JTextField	lcl_samples = MigLayoutUtils.numberText(lcl_p, "Radius", lcl_calculator.getSamples(), false);
		JButton		lcl_samplesBtn = SwingComponentFactory.makeAButton("Apply");
		lcl_samplesBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int		li_samples = Integer.parseInt(lcl_samples.getText());
				
				if(li_samples < 3) {
					SimpleAlert.doAlert("Cannot have size less than 3", null);
					return;
				}
				
				if(li_samples > 40) {
					SimpleAlert.doAlert("Cannot have size greater than 40", null);
					return;
				}
				
				lcl_calculator.setSamples(li_samples);
				mcl_brushImage.recreateBrush();
			}
			
		});
		lcl_p.add(lcl_samplesBtn, "wrap");
		
		lcl_p.add(SwingComponentFactory.makeALabel("Brush Intensity"));
		final	JSlider		lcl_slider = SwingComponentFactory.makeAHorizontalSlider(-300, 300, 0);
		lcl_p.add(lcl_slider, "wrap, grow, width 100%, span");
		lcl_slider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				lcl_calculator.getControlPoint().setLocation(lcl_slider.getValue(), lcl_calculator.getControlPoint().getY());
				mcl_brushImage.repaint();
			}
		});
		
		JLabel		lcl_applyLbl = SwingComponentFactory.makeALabel("Apply Mode");
		lcl_p.add(lcl_applyLbl);
		JComboBox		lcl_combo = SwingComponentFactory.makeAComboBox();
		lcl_combo.addItem(MixType.add);
		lcl_combo.addItem(MixType.subtract);
		lcl_combo.addItem(MixType.multiply);
		lcl_combo.addItem(MixType.replace);
		lcl_combo.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				mcl_textureImgComp.setMixType((MixType)e.getItem());
			}
			
		});
		lcl_p.add(lcl_combo, "wrap");
		
		lcl_p.add(SwingComponentFactory.makeALabel("Brush Strength"));
		final	JSlider		lcl_sliderStrength = SwingComponentFactory.makeAHorizontalSlider(1, 100, 100);
		lcl_sliderStrength.setPaintLabels(true);
		lcl_sliderStrength.setPaintTicks(true);
		lcl_sliderStrength.setMajorTickSpacing(10);
		lcl_sliderStrength.setMinorTickSpacing(5);
		lcl_p.add(lcl_sliderStrength, "wrap, grow, width 100%, span");
		lcl_sliderStrength.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				mcl_brushImage.setStrength((float)lcl_sliderStrength.getValue() / 100f);
			}
		});
		
		RGBEditorPanel		lcl_brushColor = new RGBEditorPanel();
		lcl_brushColor.setColourChangedListener(new RGBEditorPanel.IColourChanged() {
			public void colourChanged(int i_r, int i_g, int i_b) {
				mcl_textureImgComp.setPaintColours(i_r, i_g, i_b);
			}
		});
		lcl_p.add(lcl_brushColor, "wrap, span");
		
		add(lcl_p, "wrap, width 100%, span, grow");
	}
}
